/*
 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef DRIVER_ETH_MAC_H_
#define DRIVER_ETH_MAC_H_

#include "Driver_ETH.h"
#include "fff.h"

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define _ARM_Driver_ETH_MAC_(n) Driver_ETH_MAC##n
#define ARM_Driver_ETH_MAC_(n)  _ARM_Driver_ETH_MAC_(n)

#define ARM_ETH_MAC_CONFIGURE  (0x01UL) ///< Configure MAC; arg = configuration
#define ARM_ETH_MAC_CONTROL_TX (0x02UL) ///< Transmitter; arg: 0=disabled (default), 1=enabled
#define ARM_ETH_MAC_CONTROL_RX (0x03UL) ///< Receiver; arg: 0=disabled (default), 1=enabled

#define ARM_ETH_MAC_SPEED_Pos         0
#define ARM_ETH_MAC_DUPLEX_Pos        2
#define ARM_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address

#define ARM_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received

typedef void (*ARM_ETH_MAC_SignalEvent_t)(
    uint32_t event); ///< Pointer to \ref ARM_ETH_MAC_SignalEvent : Signal Ethernet Event.

typedef struct _ARM_ETH_MAC_ADDR {
    uint8_t b[6];
} ARM_ETH_MAC_ADDR;

typedef struct _ARM_ETH_MAC_CAPABILITIES {
    uint32_t event_rx_frame : 1;  ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_RX_FRAME generated
    uint32_t media_interface : 2; ///< Ethernet Media Interface type
} ARM_ETH_MAC_CAPABILITIES;

typedef int ARM_ETH_MAC_TIME;

typedef struct _ARM_DRIVER_ETH_MAC {
    ARM_ETH_MAC_CAPABILITIES(*GetCapabilities)
    (void); ///< Pointer to \ref ARM_ETH_MAC_GetCapabilities : Get driver capabilities.
    int32_t (*Initialize)(ARM_ETH_MAC_SignalEvent_t
                              cb_event); ///< Pointer to \ref ARM_ETH_MAC_Initialize : Initialize Ethernet MAC Device.
    int32_t (*PowerControl)(
        ARM_POWER_STATE state); ///< Pointer to \ref ARM_ETH_MAC_PowerControl : Control Ethernet MAC Device Power.
    int32_t (*GetMacAddress)(
        ARM_ETH_MAC_ADDR *ptr_addr); ///< Pointer to \ref ARM_ETH_MAC_GetMacAddress : Get Ethernet MAC Address.
    int32_t (*SetAddressFilter)(
        const ARM_ETH_MAC_ADDR *ptr_addr,
        uint32_t num_addr); ///< Pointer to \ref ARM_ETH_MAC_SetAddressFilter : Configure Address Filter.
    int32_t (*SendFrame)(const uint8_t *frame,
                         uint32_t len,
                         uint32_t flags); ///< Pointer to \ref ARM_ETH_MAC_SendFrame : Send Ethernet frame.
    int32_t (*ReadFrame)(
        uint8_t *frame,
        uint32_t len); ///< Pointer to \ref ARM_ETH_MAC_ReadFrame : Read data of received Ethernet frame.
    uint32_t (*GetRxFrameSize)(
        void); ///< Pointer to \ref ARM_ETH_MAC_GetRxFrameSize : Get size of received Ethernet frame.
    int32_t (*Control)(uint32_t control,
                       uint32_t arg); ///< Pointer to \ref ARM_ETH_MAC_Control : Control Ethernet Interface.
    int32_t (*PHY_Read)(uint8_t phy_addr,
                        uint8_t reg_addr,
                        uint16_t *data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Read : Read Ethernet PHY Register through
                                         ///< Management Interface.
    int32_t (*PHY_Write)(uint8_t phy_addr,
                         uint8_t reg_addr,
                         uint16_t data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Write : Write Ethernet PHY Register
                                         ///< through Management Interface.
} const ARM_DRIVER_ETH_MAC;

DECLARE_FAKE_VALUE_FUNC(ARM_ETH_MAC_CAPABILITIES, ARM_ETH_MAC_GetCapabilities);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_Initialize, ARM_ETH_MAC_SignalEvent_t);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_PowerControl, ARM_POWER_STATE);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_GetMacAddress, ARM_ETH_MAC_ADDR *);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_SetAddressFilter, const ARM_ETH_MAC_ADDR *, uint32_t);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_SendFrame, const uint8_t *, uint32_t, uint32_t);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_ReadFrame, uint8_t *, uint32_t);
DECLARE_FAKE_VALUE_FUNC(uint32_t, ARM_ETH_MAC_GetRxFrameSize);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_Control, uint32_t, uint32_t);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_PHY_Read, uint8_t, uint8_t, uint16_t *);
DECLARE_FAKE_VALUE_FUNC(int32_t, ARM_ETH_MAC_PHY_Write, uint8_t, uint8_t, uint16_t);

#ifdef __cplusplus
} // extern "C"
#endif

#endif /* DRIVER_ETH_MAC_H_ */
